package com.chenjl.trace.client;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.MDC;

import com.chenjl.trace.Tracer;
import com.chenjl.trace.enums.AnnotationEnum;
import com.chenjl.trace.enums.SpanTypeEnum;
import com.chenjl.trace.model.Endpoint;
import com.chenjl.trace.utils.Constant;
import com.chenjl.trace.utils.WebUtils;
/**
 * 跟踪调用记录filter，支持标准Servlet API容器
 * 2018-6-29 15:34:24
 * @author chenjinlong
 */
public class WebTraceFilter implements Filter {
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
		TraceHttpServletResponse httpServletResponse = new TraceHttpServletResponse((HttpServletResponse) servletResponse);
		String servletPath = httpServletRequest.getServletPath();
		String requestIp = WebUtils.getRequestIp(httpServletRequest);
		
		Endpoint endpoint = new Endpoint();
		endpoint.setServiceName("web request");
		endpoint.setHost(requestIp);
		String spanId = Tracer.beginRoot(servletPath,endpoint,AnnotationEnum.SERVER_RECEIVE,SpanTypeEnum.HTTP_API);
		MDC.put(Constant.C_TRACE_ID,spanId);
		
		boolean hasExceptionFlag = false;
		try {
			filterChain.doFilter(servletRequest,httpServletResponse);
		}
		catch(Throwable e) {
			hasExceptionFlag = true;
			throw e;
		}
		finally {
			int httpCode = httpServletResponse.getHttpStatus();
			if(httpCode == 0) {
				httpCode = hasExceptionFlag ? HttpServletResponse.SC_INTERNAL_SERVER_ERROR : HttpServletResponse.SC_OK;
			}
			
			Map<String,String> datas = new HashMap<String,String>(2);
			datas.put("httpCode",String.valueOf(httpCode));
			Tracer.end(spanId,endpoint,AnnotationEnum.SERVER_SEND,datas);
			Tracer.clear();
		}
	}
	@Override
	public void destroy() {
		
	}
}